﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Collections;

namespace ProgNetComponents.Utils
{
    public class DesignUtils
    {
        public static IContainer CheckForNestedContainer(IContainer container)
        {
            NestedContainer nestedContainer = container as NestedContainer;
            if (nestedContainer != null)
                return nestedContainer.Owner.Site.Container;
            else
                return container;
        }

        public static List<string> GetColumns(object dataSourceOwner, ITypeDescriptorContext context, IServiceProvider provider)
        {
            object dataSource = dataSourceOwner.GetPropertyValue("DataSource");
            string dataMember = dataSourceOwner.GetPropertyValue("DataMember").AsString();
            return GetColumns(dataSource, dataMember, context, provider);
        }

        public static List<string> GetColumns(object dataSource, string dataMember, ITypeDescriptorContext context, IServiceProvider provider)
        {
            List<string> columns = new List<string>();
            bool addAllData = true;
            if (dataSource != null)
            {
                if (dataSource is DataTable)
                {
                    addAllData = false;
                    AddColumns(columns, (DataTable)dataSource);
                }
                if (dataSource is DataView)
                {
                    if (((DataView)dataSource).Table != null)
                    {
                        AddColumns(columns, ((DataView)dataSource).Table);
                        addAllData = false;
                    }
                }
                if (dataSource is DataSet)
                {
                    if (dataMember != null && ((DataSet)dataSource).Tables.Contains(dataMember.AsString()))
                        AddColumns(columns, ((DataSet)dataSource).Tables[dataMember.AsString()]);
                    else
                        AddColumns(columns, ((DataSet)dataSource));
                    addAllData = false;
                }
            }
            if (!addAllData)
                return columns;

            IContainer container = (IContainer)null;
            IDesignerHost hostSvc = provider.GetService<IDesignerHost>();

            if (context != null)
                container = context.Container;
            if (container == null && hostSvc != null)
                container = hostSvc.Container;
            if (container == null)
                return columns;

            ComponentCollection components = DesignUtils.CheckForNestedContainer(container).Components;
            foreach (IComponent comp in (ReadOnlyCollectionBase)components)
            {
                DataSet ds = comp as DataSet;
                if (ds != null)
                {
                    AddColumns(columns, ds);
                }
            }
            return columns;

        }

        private static void AddColumns(List<string> collection, DataSet ds)
        {
            foreach (DataTable dt in ds.Tables)
            {
                AddColumns(collection, dt);
            }
        }

        private static void AddColumns(List<string> collection, DataTable dt)
        {
            foreach (DataColumn col in dt.Columns)
            {
                if (col.ColumnName.IsNotNull())
                    collection.AddIfNotExist(col.ColumnName);
            }
        }
    }
}
